package com.meevle.model
{
	import com.meevle.events.DataLoaderEvent;
	import com.meevle.events.GetSetListEvent;
	import com.meevle.input.MidiManager;
	
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.media.Microphone;
	
	import mx.binding.utils.ChangeWatcher;
	
	[Event(name="startLoadingData", type="com.meevle.events.DataLoaderEvent")]
	[Event(name="finishedLoadingData", type="com.meevle.events.DataLoaderEvent")]
	[Event(name="dataLoadingComplete", type="com.meevle.events.DataLoaderEvent")]
	[Event(name="errorLoadingData", type="com.meevle.events.DataLoaderEvent")]
	public class DataLoader extends EventDispatcher
	{
		private var changeWatcher:ChangeWatcher;
		private var cwError:ChangeWatcher;
		
		private static var instance:DataLoader;
		
		public function DataLoader(enforcer:SingletonEnforcer) {
		if (enforcer == null) {
				throw new Error( "You Can Only Have One DataLoader" );
			}
		}
		
		public static function getInstance() : DataLoader {
			if (instance == null) {
				instance = new DataLoader( new SingletonEnforcer );
			}
			return instance;
		}
		
		public function loadData() : void {
			cwError = ChangeWatcher.watch(ViewModelLocator.getInstance(), "error", onError);	
			loadSetList();
		}
		
		private function loadSetList() : void {
			changeWatcher = ChangeWatcher.watch(ViewModelLocator.getInstance(), "setList", onSetListChanged);
			var startLoadingSetListDataEvent:DataLoaderEvent = new DataLoaderEvent(DataLoaderEvent.START_LOADING_DATA, "Loading sets");
			dispatchEvent(startLoadingSetListDataEvent);
			var getSetListEvent:GetSetListEvent = new GetSetListEvent();
			getSetListEvent.dispatch();
		}
		
		private function onSetListChanged(event:Event) : void {
			changeWatcher.unwatch();
			var finishedLoadingSetListDataEvent:DataLoaderEvent = new DataLoaderEvent(DataLoaderEvent.FINISHED_LOADING_DATA, "Setlist successfully loaded");
			dispatchEvent(finishedLoadingSetListDataEvent);
			complete();
		}

		private function complete() : void {
			var dataLoadingCompleteDataEvent:DataLoaderEvent = new DataLoaderEvent(DataLoaderEvent.DATA_LOADING_COMPLETE, "Data loading succesfully completed");
			cwError.unwatch();
			dispatchEvent(dataLoadingCompleteDataEvent);
		}
		
		private function onError(e:Event) : void {
			var errorEvent:DataLoaderEvent = new DataLoaderEvent(DataLoaderEvent.ERROR_LOADING_DATA, ViewModelLocator.getInstance().error.message);
			dispatchEvent(errorEvent);
		}
	}
}

// Utility Class to Deny Access to Constructor
class SingletonEnforcer {}